#ifndef _ILINEBLOCK_H_
#define _ILINEBLOCK_H_

#include <BLine>
#include <BPainter>
#include <BTextFormat>
#include "ICodeCell.h"

namespace BWE
{
	class ILineBlock
	{
	public:
		ILineBlock();
		ILineBlock(const ILineBlock& other);
		~ILineBlock();

		inline void clear()
		{
			text.clear();
			reset();
		}
		inline bool empty() const
		{
			return cells.empty();
		}
		inline int home() const
		{
			for (int i = 0; i < cells.size(); i++)
			{
				if (cells[i].code == '\n')
					return i;
				if (!cells[i].code.isSpace())
					return i;
			}
			return 0;
		}
		inline int end() const
		{
			for (int i = cells.size() - 1; i >= 0; i--)
			{
				if (!cells[i].code.isSpace())
					return i + 1;
			}
			return cells.size();
		}
		inline int tail() const
		{
			int index = cells.size();
			if (cells(index - 1).code == '\n')
				index--;
			if (cells(index - 1).code == '\r')
				index--;
			return index;
		}

		inline int codeCount() const
		{
			return cells.size();
		}
		inline BCode code(int pos) const
		{
			return cells(pos).code;
		}

		void reset();
		void reset(const BString& text);
		void prepend(const BCode& code);
		void append(const BString& text);
		bool remove(int pos, int size = 1);
		bool insert(const BCode& code);
		bool insert(const BString& text);
		bool insert(int pos, const BString& text);
		void flush();

		void collect(BString& text, int pos, int count) const;
		void collect(BString& text) const;

		bool selectWord();
		bool removeSelection();

		bool seekHead();
		bool seekPoint(const BPoint& point);
		bool seekTail();

		int seekPrevCode();
		int seekNextCode();
		int seekPrevWord();
		int seekNextWord();

		int indexAt(const BPoint& pos) const;
		int wordWidth(int pos, int& end) const;

		void adjust(int width, BTextFormat* format = 0);
		void paint(BPainter& painter, BTextFormat* format = 0);

	public:
		bool		visible;
		BRange		range;
		BString		text;
		Align		align;
		bool		wordWrap;
		int			lineHeight;
		int			lineSpacing;

		bool		dirty;
		BRect		rect;
		int			index;
		int			count;
		int			rowHeight;
		BSize		textSize;

		BArray<ICodeCell>		cells;
		BHolder<const BFont>	font;
		BTextFormatHolder		format;
	};

	typedef BList<ILineBlock>			ILineBlockList;
	typedef ILineBlockList::iterator	ILineBlockIterator;

}

#endif